package com.forcht.ioc.factory;

import com.forcht.ioc.BeanDefinition;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by forcht on 2018/4/17.
 * 这里使用了工厂方法模式和模板方法模式
 */
public abstract class AbstractBeanFactory implements BeanFactory{

    private Map<String,BeanDefinition> beanDefinitionMap=new ConcurrentHashMap<>();

    private final List<String> beanDefinitionNames=new ArrayList<>();

    /**
     * 体现了模板方法
     * @param name
     * @return
     * @throws Exception
     */
    @Override
    public Object getBean(String name) throws Exception {
        BeanDefinition beanDefinition = beanDefinitionMap.get(name);
        if(beanDefinition==null){
            throw new IllegalArgumentException("No bean named " + name + " is defined");
        }
        Object bean = beanDefinition.getBean();
        if(bean==null){
            bean=doCreateBean(beanDefinition);
        }
        return bean;
    }

    public void registerBeanDefinition(String name, BeanDefinition beanDefinition) throws Exception{
        beanDefinitionMap.put(name,beanDefinition);
        beanDefinitionNames.add(name);
    }

    public void preInstantiateSingletons() throws Exception {
        Iterator<String> iterator = beanDefinitionNames.iterator();
        while (iterator.hasNext()){
            String beanName=iterator.next();
            getBean(beanName);
        }
    }
    /**
     * 创建bean
     * @param beanDefinition
     * @return
     */
    protected  abstract Object doCreateBean(BeanDefinition beanDefinition) throws Exception;
}
